None
Adwords Script 自动排除Placement

Adwords 的自动操作除了支持Rule之外还支持使用Javascript 配合Adwords API 完成更加复杂的自动化功能;详细的可以阅读Adwords Script的官方指南:

Adwords script

使用Adwords Script 比起集成API会更加简单,集成API需要大量的开发工作,Adwords Script则提供图形界面,可以随时监控脚本的运行;

#1  Adwords Script-Auto Exclude Placement

对于display ads 来说日常的Placement优化是很重要的,但是对于大型账户Placement的数量会非常多,一个个去检查是不太实际的。所以,可以设定条件去让Adwords Script去自动排除无关Placement;

假设条件如下:

根据网页后缀进行排除,如果遇见以.org, .pl, 等后缀结尾的Placement就要在相应的广告系列和广告组执行排除操作

脚本的实现其实不难,看完Google官方的示例大致就只需要三个模块:

  1. 取得Placement 数据
  2. 根据条件执行排除操作
  3. 如果需要记录的话生成相应的记录文件,方便查找

脚本如下:

var TLDs = ['.cn' , '.hk','.in','.pk', '.tr','.ru'];
//var TLDs = ['.info','.br'];
var timePeriod = "LAST_30_DAYS"; 
var reportRows = [];
var exflag = "exclude"
// you need clone a sheet first click the following SPREADSHEET_URL
// click make a copy to clone the template
// paste your SPREADSHEET_URL to replace the following SPREADSHEET_URL
var SPREADSHEET_URL = 'https://docs.google.com/spreadsheets/d/1Exyhk0MopoLCqftIiJuTwQK1z2x9IECXyRwK1BsOSmw/edit#gid=0'
  //Logger.log('Using spreadsheet - %s.', SPREADSHEET_URL);
  var spreadsheet = validateAndGetSpreadsheet(SPREADSHEET_URL);
  var sheet = spreadsheet.getSheets()[0];
// -------------------------------------------------------

function removePlacementByDomain (domain,leg) {
  var placementSelector = AdWordsApp.display().placements()
  .withCondition("PlacementUrl CONTAINS '" + domain + "'")
  .withCondition("CampaignStatus != REMOVED")
  .forDateRange(timePeriod)
  .withLimit(100);
  
  
  var placementIterator = placementSelector.get();
  while (placementIterator.hasNext()) {
    var placement = placementIterator.next();
    var placementUrl = placement.getUrl();
    //Logger.log(placementUrl);
    var s = 0-leg
    var p = placementUrl.slice(s);
    if (p == domain){
    var campaign = placement.getCampaign();
	//var adgroup = placement.getAdGroup();
    var excludeOperation = campaign.display().newPlacementBuilder().withUrl(placementUrl).exclude();
	reportRows.push([placement.getCampaign().getName(),placement.getAdGroup().getName(),placementUrl,exflag]);
    Logger.log(" exclude : " + placementUrl)
    if (!excludeOperation.isSuccessful()) {
      Logger.log("Could not exclude : " + placementUrl);
	  exflag = "Could not exclude"
	  reportRows.push([campaign,adgroup,placementUrl,exflag]);
    }
  }
  }

}
function trm(domain){
  return domain.trim();
}

function run () {
  
  Logger.log('Using spreadsheet - %s.', SPREADSHEET_URL);
  spreadsheet.setSpreadsheetTimeZone(AdWordsApp.currentAccount().getTimeZone());
    spreadsheet.getRangeByName('account_id').setValue(
      AdWordsApp.currentAccount().getCustomerId());
  sheet.getRange(1, 2, 1, 1).setValue('Date');
  sheet.getRange(1, 3, 1, 1).setValue(new Date());
  //sheet.getRange(7, 1, sheet.getMaxRows() - 7, sheet.getMaxColumns()).clear();
  Logger.log('Running on .' + AdWordsApp.currentAccount().getCustomerId());
  var lastRow = sheet.getLastRow();

  for (var i = 0; i < TLDs.length; i++){
    var dom = trm(TLDs[i])
    removePlacementByDomain(dom,dom.length)
  }
 
  Logger.log('all:'+reportRows.length)
    if (reportRows.length > 0) {
    sheet.getRange(lastRow+1, 2, 1, 1).setValue(new Date());
  sheet.getRange(lastRow+2, 2, reportRows.length, 4).setValues(reportRows);
  }
  var email = spreadsheet.getRangeByName('email').getValue();
    if (email) {
    var body = [];
    body.push('The Account Placement exclude history :\n');
	body.push('Account ID:' +AdWordsApp.currentAccount().getCustomerId());
    body.push('Full report at ' + SPREADSHEET_URL + '\n\n');
    }
    MailApp.sendEmail(email, '' +
        reportRows.length + ' The  Placement Auto Exclude ' +
        AdWordsApp.currentAccount().getName(), body.join('\n'));
}

function executeInSequence (sequentialIds, executeSequentiallyFunc) {
  Logger.log('Executing in sequence : ' + sequentialIds);
  sequentialIds.forEach(function (accountId) {
    var account = MccApp.accounts().withIds([accountId]).get().next();
    MccApp.select(account);
    executeSequentiallyFunc();
  });
}


function main(){

      Logger.log('Running on non-MCC account.');
      run();
} 

 function validateAndGetSpreadsheet(spreadsheeturl) {
  if (spreadsheeturl == 'YOUR_SPREADSHEET_URL') {
    throw new Error('Please specify a valid Spreadsheet URL. You can find' +
        ' a link to a template in the associated guide for this script.');
  }
  return SpreadsheetApp.openByUrl(spreadsheeturl);
}

 

#2 脚本执行

以上脚本看起来很复杂,实际上核心的功能很简单,只不过把记录写进Google sheet 需要的代码比较多,如果不需要这部分完全可以更加简洁;

在执行脚本前:

  1. 去copy 一份存取记录的Google sheet 模板;模板地址:Template
  2. 点击模板的 make a copy, 把你自己的模板链接复制到代码中var SPREADSHEET_URL = 的位置,并替换原来的链接
  3. 在变量 var TLDs 数组里增加想要拍出的PL后缀,用逗号分隔

执行脚本:

  1. 登录Adwords Script在BULK ACTIONS >> Script 下新建一个脚本,命名
  2. 全选复制以上代码,复制进新建的Adwords Script中
  3. 点击预览,观察输出,会把相应的存有记录的Google sheet链接输出出来,如果在模板中填写了电子邮箱,则会把报告发送到邮箱
  4. 没有问题的话就点击保存,设置运行的事件

实际上,如果需要按照点击或者转化等数据执行排除操作也很简单,只需要改写一下执行Exclude动作的函数即可,用with_condition拿出数据之后就直接执行排除排除,不用像这里要进行判断

# 3 根据账户数据排除PL

排除条件:

  1. 过去30天,展示超过1000并且花费大于50,转化为0的PL
  2. 不包含 anonymous.google这个PL

 

在执行脚本前:

  1. 去copy 一份存取记录的Google sheet 模板;模板地址:Template
  2. 点击模板的 make a copy, 把你自己的模板链接复制到代码中var SPREADSHEET_URL = 的位置,并替换原来的链接
  3. 将即便满足条件也不需要排除的PL,添加到 enablelist = ['anonymous.google'] 后

脚本如下:

var impressionsMinimum = 1000; // Select Display placements which have at least that number of impressions 
//var maxCtr = 0.001; // Select Display placements which have at least that Click Through Rate percentage 
var conversionsLimit = 0; // Select Display placements which have no more than that number of conversions 
var ViewThroughConversionsLimit = 0; // Select Display placements which have no more than that number of post-impression conversions 
var cost = 50
var timePeriod = "LAST_30_DAYS"; // Period of time to analyze. You can choose another value according to https://developers.google.com/adwords/scripts/docs/reference/adwordsapp/adwordsapp_campaignselector?hl=es-419#forDateRange_1  							  							  
var enablelist = ['anonymous.google']
var reportRows = [];
var exflag = "exclude"
var SPREADSHEET_URL = 'https://docs.google.com/spreadsheets/d/1bKZ0aTD9dMYdkvzBclkI5ljXVfoNOe5c4ZbqUZQT18I/edit#gid=0'
  var spreadsheet = validateAndGetSpreadsheet(SPREADSHEET_URL);
  var sheet = spreadsheet.getSheets()[0];
// -------------------------------------------------------


function main(){

      Logger.log('Running on non-MCC account.');
      run();
} 



function exclude () {
  var DisplayPlacements = AdWordsApp.display().placements()
 	//.withCondition("Ctr > "+maxCtr)
    .withCondition("Cost > "+cost)
	.withCondition("Impressions >= "+impressionsMinimum)
    .withCondition("Conversions <= "+conversionsLimit)
	.withCondition("ViewThroughConversions <= "+ViewThroughConversionsLimit)
	.withCondition("CampaignStatus != REMOVED")
	.forDateRange(timePeriod)
    .get();
    
  var placementurl;
  var placement;
  
  while (DisplayPlacements.hasNext()) {
   
    placement = DisplayPlacements.next();

    placementurl = placement.getUrl();
    Logger.log(placementurl);
    
	var campaign = placement.getCampaign();
    var adGroup = placement.getAdGroup();    
    if (enablelist.indexOf(placementurl) == -1){
      var excludeOperation = adGroup.display().newPlacementBuilder().withUrl(placementurl).exclude(); // Exclude Display placement detected
	  	reportRows.push([placement.getCampaign().getName(),placement.getAdGroup().getName(),placementUrl,exflag]);
    Logger.log(" exclude : " + placementUrl)

      if (!excludeOperation.isSuccessful()) {
		Logger.log("Could not exclude : " + placementurl);
		exflag = "Could not exclude"
	  reportRows.push([campaign,adgroup,placementUrl,exflag]);
	  }	 
    } else { 
      Logger.log("Don't exclude Enablelist PlacementUrl !");
	}
  }  
}


function run () {
  
  Logger.log('Using spreadsheet - %s.', SPREADSHEET_URL);
  spreadsheet.setSpreadsheetTimeZone(AdWordsApp.currentAccount().getTimeZone());
    spreadsheet.getRangeByName('account_id').setValue(
      AdWordsApp.currentAccount().getCustomerId());
  sheet.getRange(1, 2, 1, 1).setValue('Date');
  sheet.getRange(1, 3, 1, 1).setValue(new Date());
  sheet.getRange(7, 1, sheet.getMaxRows() - 7, sheet.getMaxColumns()).clear();
  Logger.log('Running on .' + AdWordsApp.currentAccount().getCustomerId());
  
  exclude();

  
  Logger.log('all:'+reportRows.length)
    if (reportRows.length > 0) {
  sheet.getRange(7, 2, reportRows.length, 4).setValues(reportRows);
  }
  var email = spreadsheet.getRangeByName('email').getValue();
    if (email) {
    var body = [];
    body.push('The Account Placement exclude history :\n');
	body.push('Account ID:' +AdWordsApp.currentAccount().getCustomerId());
    body.push('Full report at ' + SPREADSHEET_URL + '\n\n');
    }
    MailApp.sendEmail(email, '' +
        reportRows.length + ' The Auto Placement Exclude ' +
        AdWordsApp.currentAccount().getName(), body.join('\n'));
}

function executeInSequence (sequentialIds, executeSequentiallyFunc) {
  Logger.log('Executing in sequence : ' + sequentialIds);
  sequentialIds.forEach(function (accountId) {
    var account = MccApp.accounts().withIds([accountId]).get().next();
    MccApp.select(account);
    executeSequentiallyFunc();
  });
}







 function validateAndGetSpreadsheet(spreadsheeturl) {
  if (spreadsheeturl == 'YOUR_SPREADSHEET_URL') {
    throw new Error('Please specify a valid Spreadsheet URL. You can find' +
        ' a link to a template in the associated guide for this script.');
  }
  return SpreadsheetApp.openByUrl(spreadsheeturl);
}

执行成功后到相应的Template检查排除结果。如果需要改变相应的排除条件请修改:

  var DisplayPlacements = AdWordsApp.display().placements()
 	//.withCondition("Ctr > "+maxCtr)
    .withCondition("Cost > "+cost)
	.withCondition("Impressions >= "+impressionsMinimum)
    .withCondition("Conversions <= "+conversionsLimit)
	.withCondition("ViewThroughConversions <= "+ViewThroughConversionsLimit)
	.withCondition("CampaignStatus != REMOVED")
	.forDateRange(timePeriod)
    .get();

把相应的我ithCondition里的参数修改成想要的排除条件即可。具体的参数排除可以参考 Adwords Script官方说明:

Adwords Script WithCondition


Comments:
Share With :